package com.shuaigexue.aicodegenerate.controller;

import cn.hutool.core.bean.BeanUtil;
import com.mybatisflex.core.paginate.Page;
import com.shuaigexue.aicodegenerate.annotation.AuthCheck;
import com.shuaigexue.aicodegenerate.common.BaseResponse;
import com.shuaigexue.aicodegenerate.common.DeleteRequest;
import com.shuaigexue.aicodegenerate.common.ResultUtils;
import com.shuaigexue.aicodegenerate.constant.UserConstant;
import com.shuaigexue.aicodegenerate.exception.BusinessException;
import com.shuaigexue.aicodegenerate.exception.ErrorCode;
import com.shuaigexue.aicodegenerate.exception.ThrowUtils;
import com.shuaigexue.aicodegenerate.model.dto.user.*;
import com.shuaigexue.aicodegenerate.model.vo.LoginUserVO;
import com.shuaigexue.aicodegenerate.model.vo.UserVO;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import com.shuaigexue.aicodegenerate.entity.User;
import com.shuaigexue.aicodegenerate.service.UserService;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

/**
 * 用户 控制层。
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;


    /**
     * 用户注册
     *
     * @param userRegisterRequest 用户注册请求
     * @return 用户信息
     */
    @PostMapping("/register")
    public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest){
        ThrowUtils.throwIf(userRegisterRequest == null, ErrorCode.PARAMS_ERROR);

        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        long result = userService.userRegister(userAccount, userPassword, checkPassword);
        return ResultUtils.success(result);
    }

    /**
     * 用户登录
     *
     * @param userLoginRequest 用户登录请求
     * @return 用户信息
     */
    @PostMapping("/login")
    public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request
    ){
        ThrowUtils.throwIf(userLoginRequest == null , ErrorCode.PARAMS_ERROR);
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(loginUserVO);
    }

    /**
     * 获取当前登录用户
     *
     * @param request 请求
     * @return 登录用户
     */

    @GetMapping("/get/login")
    public BaseResponse<LoginUserVO> getLoginUser(HttpServletRequest request){
        // 获取当前登陆用户
        User loginUser = userService.getLoginUser(request);

        // 返回登陆后脱敏用户
        return ResultUtils.success(userService.getLoginUserVO(loginUser));
    }

    /**
     * 用户注销
     * @param request 请求
     * @return 登出成功
     */
    @PostMapping("/logout")
    public BaseResponse<Boolean> userLogout(HttpServletRequest request){
        ThrowUtils.throwIf(request == null, ErrorCode.PARAMS_ERROR);
        Boolean userLoginStatus = userService.UserLogout(request);
        return ResultUtils.success(userLoginStatus);
    }

    /**
     * 管理员创建用户
     * @param userAddRequest
     * @return
     * des:我们添加用户，这个接口是给管理员用的，管理员可以添加用户，但是用户不能添加管理员。添加权限注释
     * 当添加一个新的用户时候，模拟用户的一个状态，用户进行注册后，
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/add")
    public BaseResponse<Long> addUser(@RequestBody UserAddRequest userAddRequest){
        ThrowUtils.throwIf(userAddRequest == null, ErrorCode.PARAMS_ERROR);
        User user = new User();
        BeanUtil.copyProperties(userAddRequest,user);

        // 设置一个默认的密码
        final String DEFAULT_USER_PASSWORD = "12345678";
        // 为默认密码加盐处理
        String encryptPassword = userService.getEncryptPassword(DEFAULT_USER_PASSWORD);

        // 将用户的密码设置成加盐后密码
        user.setUserPassword(encryptPassword);

        // 保存用户
        boolean result = userService.save(user);

        // 保存用户失败的话,抛出错误
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 保存成功，将结果返回给前端，前端展示添加成功页面
        /**
         * 返回用户ID而不是保存结果的原因
         * user.getId() 是新创建用户的唯一标识符，对前端更有实际价值
         * 前端通常需要新创建用户的ID来进行后续操作
         * 例如：跳转到用户详情页、关联其他数据等操作都需要用到用户ID
         * 对于创建资源的API，通常返回新创建资源的标识符是更标准的做法
         */
        return ResultUtils.success(user.getId());
    }


    /**
     * 根据用户id获取用户信息(仅管理员)
     * @param id
     * @return
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @GetMapping("/get")
    public BaseResponse<User> getUserById(long id){
        // 判断id是否合法
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        User user = userService.getById(id);
        // 判断用户是否存在
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(user);
    }

    /**
     * 根据用户id获取用户脱敏信息
     * @param id
     * @return
     */
    @AuthCheck(mustRole = UserConstant.DEFAULT_ROLE)
    @GetMapping("/get/vo")
    public BaseResponse<UserVO> getUserVOById(long id) {
        // 获取用户
        BaseResponse<User> response = getUserById(id);
        User user = response.getData();
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(userService.getUserVO(user));
    }

    /**
     * 删除用户 (仅管理员)
     * @param deleteRequest
     * @return
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest){
        // 判断请求是否为空或用户ID小于等于0，则抛出参数错误异常
        if(deleteRequest == null || deleteRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 不为空，则进行删除
        boolean b = userService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    /**
     * 更新用户信息 (仅管理员)
     * 这里使用PostMapping，而不是PutMapping，因为现在的功能仅对于管理员更新普通用户的信息
     * 用户自己更新信息的功能使用的putmapping
     * @param userUpdateRequest
     * @return
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest){
        // 判断请求是否为空或 用户ID为空，则抛出参数错误异常
        if(userUpdateRequest == null || userUpdateRequest.getId() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = new User();
        BeanUtil.copyProperties(userUpdateRequest,user);

        // 更新到数据库
        boolean b = userService.updateById(user);
        ThrowUtils.throwIf(!b, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(b);
    }

    /**
     * 获取用户列表 (仅管理员)
     * @param userQueryRequest
     * @return
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<UserVO>> listUserVoByPage(@RequestBody UserQueryRequest userQueryRequest) {
        ThrowUtils.throwIf(userQueryRequest == null, ErrorCode.PARAMS_ERROR);
        long pageNum = userQueryRequest.getPageNum();
        long pageSize = userQueryRequest.getPageSize();


        // 执行分页查询：创建分页对象并结合查询条件获取用户分页数据
//        Page<User> userPage = userService.page(Page.of(pageNum, pageSize), userService.getQueryWrapper(userQueryRequest));
        Page<User> userPage = userService.page(Page.of(pageNum, pageSize), userService.getQueryWrapper(userQueryRequest));

        // 创建一个新的分页对象用于存储脱敏后的用户信息
        Page<UserVO> userVOPage = new Page<>(pageNum, pageSize, userPage.getTotalRow());

        // 将查询到的用户列表转换为脱敏后的用户视图对象列表
        List<UserVO> userVOList = userService.getUserVOList(userPage.getRecords());

        // 将脱敏后的用户列表设置到分页对象中
        userVOPage.setRecords(userVOList);

        // 返回成功的响应结果，包含分页的用户视图对象
        return ResultUtils.success(userVOPage);
    }
    /**
     * 保存用户。
     *
     * @param user 用户
     * @return {@code true} 保存成功，{@code false} 保存失败
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("save")
    public boolean save(@RequestBody User user) {
        return userService.save(user);
    }

    /**
     * 根据主键删除用户。
     *
     * @param id 主键
     * @return {@code true} 删除成功，{@code false} 删除失败
     */
    @DeleteMapping("remove/{id}")
    public boolean remove(@PathVariable Long id) {
        return userService.removeById(id);
    }

    /**
     * 根据主键更新用户。
     *
     * @param user 用户
     * @return {@code true} 更新成功，{@code false} 更新失败
     */
    @PutMapping("update")
    public boolean update(@RequestBody User user) {
        return userService.updateById(user);
    }

    /**
     * 查询所有用户。
     *
     * @return 所有数据
     */
    @GetMapping("list")
    public List<User> list() {
        return userService.list();
    }

    /**
     * 根据主键获取用户。
     *
     * @param id 用户主键
     * @return 用户详情
     */
    @GetMapping("getInfo/{id}")
    public User getInfo(@PathVariable Long id) {
        return userService.getById(id);
    }

    /**
     * 分页查询用户。
     *
     * @param page 分页对象
     * @return 分页对象
     */
    @GetMapping("page")
    public Page<User> page(Page<User> page) {
        return userService.page(page);
    }

}
